package com.darin.cl.task;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor.AbortPolicy;
import java.util.concurrent.TimeUnit;

import android.util.Log;

import com.darin.cl.task.CLTask.CLFutureTask;
import com.darin.cl.task.CLTask.Status;

/**
 * Task管理器(包括执行,销毁Task管理器)
 * 
 * @author jianfeng.lao
 * @version 1.0
 * @CreateDate 2013-10-29
 */
public class CLTaskManager {
	private static final String TAG = "CLTaskManager";
	private static final int KEEP_ALIVE = 0;
	private ThreadPoolExecutor mThreadPoolExecutor;
	private BlockingQueue<Runnable> mThreadList = null;
	private HashMap<String, CLFutureTask> mRunningTasks;
	
	private boolean mShutdown=true;//判断线程池是否关闭
	private int maximum_pool_size;
	private int core_pool_size;

	public CLTaskManager() {
		this(10, 5, 5);
	}

	public CLTaskManager(int queueSize, int core_pool_size, int maximum_pool_size) {
		super();
		this.core_pool_size=core_pool_size;
		this.maximum_pool_size=maximum_pool_size;
		mRunningTasks = new HashMap<String, CLFutureTask>();
		mThreadList = new ArrayBlockingQueue<Runnable>(queueSize);
		initThreadPool();
	}
	
	public void initThreadPool(){
		if (mThreadPoolExecutor == null||mShutdown) {
			mThreadPoolExecutor = new ThreadPoolExecutor(core_pool_size, maximum_pool_size, KEEP_ALIVE,
					TimeUnit.SECONDS, mThreadList,
					new AbortPolicy()) {

				@Override
				protected void beforeExecute(Thread t, Runnable r) {
					// Log.v(TAG, "beforeExecute>>" + t + "," + r);
					if (r instanceof CLFutureTask) {
						CLFutureTask task = (CLFutureTask) r;
						mRunningTasks.put(task.getName(), task);
					}
				}

				@Override
				protected void afterExecute(Runnable r, Throwable t) {
					// Log.v(TAG, "afterExecute>>" + t + "," + r);
					if (r instanceof CLFutureTask) {
						CLFutureTask task = (CLFutureTask) r;
						if (mRunningTasks.containsKey(task.getName())) {
							mRunningTasks.remove(task.getName());
						}
					}
				}

			};
			mShutdown=false;
		}
	}

	/**
	 * 执行Task
	 * 
	 * @param task
	 * @author Jianfeng.Lao
	 * @CreateDate 2013年11月15日
	 */
	public <Params, Progress, Result> void execute(CLTask<Params, Progress, Result> task) {
		execute(task, null);
	}

	/**
	 * 执行Task
	 * 
	 * @param task
	 * @param params
	 * @author Jianfeng.Lao
	 * @CreateDate 2013年11月15日
	 */
	public <Params, Progress, Result> void execute(CLTask<Params, Progress, Result> task, Params... params) {
		if (mThreadPoolExecutor != null && task != null) {
			task.reset();
			task.setParams(params);
			mThreadPoolExecutor.execute(task.getCLFutureTask());
		}
	}

	/**
	 * 关闭线程池,如果当前还有Task在running,会调用onCancel();
	 * 
	 * @author jianfeng.lao
	 * @CreateDate 2013-10-29
	 */
	public void destory() {
		System.out.println("destory>>TaskManager");
		if (mThreadPoolExecutor != null) {
			mShutdown=true;
			if (mRunningTasks != null) {
				Iterator<Entry<String, CLFutureTask>> iterator = mRunningTasks.entrySet().iterator();
				while (iterator.hasNext()) {
					Entry<String, CLFutureTask> entry = iterator.next();
					CLFutureTask task = entry.getValue();
					if (task != null && !Status.FINISHED.equals(task.getStatus())) {
						task.cancel(true);
					}
				}
			}
			List<Runnable> shutDownList = mThreadPoolExecutor.shutdownNow();
			System.out.println("shutDownList>>" + shutDownList.size());
			for (int i = 0; i < shutDownList.size(); i++) {
				Runnable runnable = shutDownList.get(i);
				if (runnable instanceof CLFutureTask) {
					CLFutureTask task = (CLFutureTask) runnable;
					System.out.println("interrupt Task>>" + task);
					task.cancel(true);
				}
			}
			mRunningTasks.clear();
			mThreadList.clear();
			System.out.println("TaskManager isShutdown>>" + mThreadPoolExecutor.isShutdown());
		}
	}

	public boolean isShutdown() {
		return mShutdown;
	}

	public void setIsShutdown(boolean mIsShutdown) {
		this.mShutdown = mIsShutdown;
	}
	
	

}
